﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using Joel.Vishnu.AccesoDatos.Interfaces;
using Joel.Vishnu.AccesoDatos.SQL_Server;
using Joel.Vishnu.Modelo.Entidades;

namespace Joel.Vishnu.Repositorios
{
    public class RepositorioFactura : RepositorioEntidad<Factura, Int32>
    {
        #region Constructores

        public RepositorioFactura()
            : base()
        {
            servicioDatosFactura = new ServicioDatosFactura();
            repositorioProducto = new RepositorioProducto();
            repositorioCliente = new RepositorioCliente();
            repositorioEmpleado = new RepositorioEmpleado();
        }

        #endregion

        #region Atributos

        private IServicioDatosFactura servicioDatosFactura;
        private RepositorioProducto repositorioProducto;
        private RepositorioCliente repositorioCliente;
        private RepositorioEmpleado repositorioEmpleado;

        #endregion

        #region Propiedades

        public IServicioDatosFactura ServicioDatosFactura
        {
            get { return servicioDatosFactura; }
            set { servicioDatosFactura = value; }
        }

        #endregion

        #region Metodos

        protected override Factura FilaAEntidad(DataRow fila)
        {
            Factura factura = new Factura();
            factura.Id = (Int32)fila["FacturaId"];
            factura.Cliente = repositorioCliente.DevolverPorId((Int32)fila["ClienteId"]);
            factura.Empleado = repositorioEmpleado.DevolverPorId((Int32)fila["EmpleadoId"]);
            factura.FechaHora = (DateTime)fila["FechaHora"];
            factura.Detalles = TablaAListaFacturaDetalle(ServicioDatosFactura.Facturas_DevolverPorId(factura.Id).Tables[1], factura);
            factura.Iva = (Decimal)fila["Iva"];
            return factura;
        }

        private FacturaDetalle FilaAFacturaDetalle(DataRow fila, Factura factura)
        {
            FacturaDetalle facturaDetalle = new FacturaDetalle();
            facturaDetalle.Id = (Int32)fila["FacturaDetalleId"];
            facturaDetalle.Factura = factura;
            facturaDetalle.Producto = repositorioProducto.DevolverPorId((Int32)fila["ProductoId"]);
            facturaDetalle.Precio = (Decimal)fila["Precio"];
            facturaDetalle.Cantidad = (Int32)fila["Cantidad"];
            return facturaDetalle;
        }

        private List<FacturaDetalle> TablaAListaFacturaDetalle(DataTable tabla, Factura factura)
        {
            List<FacturaDetalle> lista = new List<FacturaDetalle>();
            foreach (DataRow fila in tabla.Rows)
            {
                lista.Add(FilaAFacturaDetalle(fila, factura));
            }
            return lista;
        }

        public override Factura DevolverPorId(Int32 id)
        {
            var entidad = entidades.Where(x => x.Id == id).FirstOrDefault();
            if (entidad == null)
                using (var ds = ServicioDatosFactura.Facturas_DevolverPorId(id))
                    if (ds.Tables[0].Rows.Count != 0)
                    {
                        entidad = FilaAEntidad(ds.Tables[0].Rows[0]);
                        entidades.Add(entidad);
                    }
            return entidad;
        }

        public List<Factura> DevolverTodos()
        {
            using (var ds = ServicioDatosFactura.Facturas_DevolverTodos())
            {
                entidades = TablaALista(ds.Tables[0]);
                foreach (var item in entidades)
                {
                    item.Detalles = TablaAListaFacturaDetalle(ServicioDatosFactura.Facturas_DevolverPorId(item.Id).Tables[1], item);
                }
            }
            return entidades;
        }

        public void Insertar(Factura entidad)
        {
            entidad.Id = ServicioDatosFactura.Facturas_Insertar(entidad.Cliente.Id, entidad.Empleado.Id, entidad.FechaHora, entidad.Iva);
        }

        public void InsertarDetalles(FacturaDetalle entidad, Factura factura)
        {
            entidad.Id = ServicioDatosFactura.FacturaDetalles_Insertar(factura.Id, entidad.Producto.Id, entidad.Producto.PrecioLista, entidad.Cantidad);
        }

        #endregion
    }
}
